package com.ruoyi.flowable.listener;

import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.flowable.domain.vo.FlowTaskVo;
import com.ruoyi.flowable.service.IFlowTaskService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.stereotype.Component;

/**
 * 任务监听器
 * <p>
 * create（创建）:在任务被创建且所有的任务属性设置完成后才触发
 * assignment（指派）：在任务被分配给某个办理人之后触发
 * complete（完成）：在配置了监听器的上一个任务完成时触发
 * delete（删除）：在任务即将被删除前触发。请注意任务由completeTask正常完成时也会触发
 *
 * @author Tony
 * @date 2021/4/20
 */
@Slf4j
@Component
public class FlowTaskListener implements TaskListener {

//    @Resource
//    private IFlowTaskService taskService;

    @Override
    public void notify(DelegateTask delegateTask) {

        log.info("任务监听器:{}", delegateTask);
        // TODO  获取事件类型 delegateTask.getEventName(),可以通过监听器给任务执行人发送相应的通知消息
        try {
            // 手动获取 Spring Bean
            IFlowTaskService taskService = SpringUtils.getBean(IFlowTaskService.class);
            String taskId = delegateTask.getId();
            String taskName = delegateTask.getName();
            System.out.println("自动驳回监听器触发, 任务ID: " + taskId + ", 任务名称: " + taskName);
            // 获取流程变量
            Boolean flag = (Boolean) delegateTask.getVariable("flag");
            String rejectReason = "包装破损，自动驳回";

            if (flag != null && flag) {
                // 使用异步方式执行驳回，避免事务冲突
                new Thread(() -> {
                    // 等待一小段时间，让当前任务完成事务提交
                    try {
                        Thread.sleep(1000);
                        // 调用驳回逻辑(taskId和comment)
                        FlowTaskVo flowTaskVo = new FlowTaskVo();
                        flowTaskVo.setTaskId(taskId);
                        flowTaskVo.setComment(rejectReason);
                        taskService.taskReject(flowTaskVo);
                        System.out.println("自动驳回执行完成: " + taskId);
                    } catch (InterruptedException e) {
                        log.error("异步驳回失败", e);
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("自动驳回失败: " + e.getMessage());
        }
    }
}
